<template>
  <div class="index-container">
    <div class="chat-area">
      <div class="chat-wrapper">
        <div class="messages scroll" ref="messages">
          <div
            class="role-chat-box"
            v-for="(item, index) in messages"
            :key="index"
          >
            <div v-if="item.Role === 'user'" class="own">
              <div class="message">
                <div class="name">用户</div>
                <div class="content">{{ item.Content }}</div>
              </div>
              <div
                class="headimg"
                :style="`background-image:url(${require('@/assets/user.png')})`"
              ></div>
            </div>
            <div v-if="item.Role === 'assistant'" class="other">
              <div
                class="headimg"
                :style="`background-image:url(${require('@/assets/logo.png')})`"
              ></div>
              <div class="message">
                <div class="name">小猿</div>
                <div class="content">
                  <chat-content :markdown="item.Content"></chat-content>
                </div>
              </div>
            </div>
          </div>
          <div class="bottom" ref="bottom"></div>
        </div>
      </div>
      <div class="chat-form">
        <form ref="chat-form" class="chat-form-el" @submit.prevent="sendMsg">
          <textarea
            ref="input"
            class="input scroll"
            v-model="form.Content"
            placeholder="发送消息给助手..."
          />
          <div class="button" :class="answered ? '' : 'button-none'"></div>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
import { chat } from "@/api/index.js";
import chatContent from "./chatContent.vue";
/**
 * 防抖函数
 * @param {function} fn 防抖函数
 * @param {number} delay 防抖时间
 */
const debounce = function (fn, delay) {
  let timer = null;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      return fn.apply(this, ...arguments);
    }, delay);
  };
};

export default {
  name: "LittleApeFrameworkIndex",

  components: {
    chatContent,
  },

  data() {
    return {
      form: {
        Role: "user",
        Content: "",
      },
      messages: [],
      answered: true,
      clearWhile: false,
      mdStr: "",
    };
  },

  computed: {
    showCousor() {
      if (this.answered) {
        return null;
      } else {
        return this.messages.length - 1;
      }
    },
  },

  mounted() {
    this.$refs.input.addEventListener("keydown", this.keyDown);
  },

  methods: {
    // textarea 回车事件处理
    keyDown(event) {
      if (event.key === "Enter" && !event.shiftKey && !event.ctrlKey) {
        event.preventDefault(); // 阻止回车键的默认换行行为
        this.sendMsg();
      }
    },
    // 发送消息
    sendMsg() {
      let form = JSON.parse(JSON.stringify(this.form));
      if (form.Content.trim() !== "" && this.answered) {
        this.messages.push(form);
        this.reset();
        this.scrollToElement();
        let url = chat(this.messages).url;
        let config = chat(this.messages).config;
        let answer = {
          Role: "assistant",
          Content: "",
        };
        this.messages.push(answer);
        let index = this.messages.length - 1;
        this.answered = false;
        this.getMsg(url, config, index);
      }
    },
    // 获取消息
    async getMsg(url, config, index) {
      this.mdStr = "";
      try {
        const response = await fetch(url, config);
        if (!response.ok) {
          this.answered = true;
          this.messages.splice(index, 1);
          this.messages.splice(index - 1, 1);
          this.$message.error(response.statusText);
          return;
        }
        const reader = response.body.getReader();
        const textDecoder = new TextDecoder();
        while (1) {
          const { done, value } = await reader.read();
          if (done) {
            this.answered = true;
            this.scrollToElement();
            break;
          }
          this.messages[index].Content = textDecoder.decode(value);
          this.scrollToElement();
          if (this.clearWhile) {
            break;
          }
        }
      } catch (error) {
        this.answered = true;
        this.$message.error(error);
      }
    },
    /**
     * 消息自动滚动
     */
    scrollToElement: debounce(function () {
      this.$nextTick(() => {
        const chatBottom = this.$refs.bottom;
        if (chatBottom) {
          chatBottom.scrollIntoView({
            behavior: "smooth",
            inline: "end",
            block: "end",
          });
        }
      });
    }, 50),
    /**
     * 重置消息表单
     */
    reset() {
      this.form = {
        Role: "user",
        Content: "",
      };
    },
  },

  beforeDestroy() {
    this.clearWhile = true;
  },
};
</script>

<style lang="scss" scoped>
.index-container {
  width: 100%;
  height: 100%;

  .chat-area {
    margin: auto;
    width: 100%;
    max-width: 1200px;
    height: 100%;
    display: flex;
    flex-direction: column;

    .chat-wrapper {
      width: 100%;
      height: 0;
      flex: 1;

      .messages {
        padding: 10px 20px;
        width: 100%;
        height: 100%;
        box-sizing: border-box;

        .role-chat-box {
          margin-bottom: 5px;
          width: 100%;

          .own,
          .other {
            width: 100%;
            display: flex;
            $headimgSize: 30px;

            .headimg {
              width: $headimgSize;
              height: $headimgSize;
              border-radius: 50%;
              background-image: var(--headimg);
              background-size: cover;
              overflow: hidden;
              border: 1px solid #efefef;
              box-sizing: border-box;
            }

            .message {
              width: calc(100% - (($headimgSize + 10px) * 2));
              display: flex;
              flex-direction: column;
              scroll-behavior: smooth;

              .name {
                margin-bottom: 9px;
                width: 100%;
                height: $headimgSize;
                line-height: $headimgSize;
                font-size: 14px;
                color: #313131;
              }

              .content {
                padding: 10px 20px;
                width: fit-content;
                max-width: 100%;
                height: auto;
                font-size: 16px;
                line-height: 24px;
                color: #313131;
                box-sizing: border-box;
                border-radius: 5px;
              }
            }
          }

          .own {
            justify-content: flex-end;
            .message {
              align-items: flex-end;
              .name {
                text-align: right;
              }
              .content {
                text-align: right;
                background: rgba($color: #55e9bc, $alpha: 0.5);
              }
            }
            .headimg {
              margin-left: 10px;
            }
          }

          .other {
            justify-content: flex-start;
            .message {
              align-items: flex-start;
              .name {
                text-align: left;
              }
              .content {
                text-align-last: left;
                background: rgba($color: #ecf6ff, $alpha: 0.5);
              }
            }
            .headimg {
              margin-right: 10px;
            }
          }
        }

        .bottom {
          width: 100%;
          height: 20px;
        }
      }
    }

    .chat-form {
      $height: 80px;
      padding: 10px;
      width: 100%;
      height: $height;
      border-radius: 10px;
      border: 2px solid #efefef;
      box-sizing: border-box;

      .chat-form-el {
        width: 100%;
        height: 100%;
        display: flex;

        .input {
          margin-right: 20px;
          padding: 5px 15px;
          width: calc(100% - 20px);
          height: 100%;
          border: none;
          outline: none;
          font-size: 16px;
          line-height: 24px;
          font-family: inherit;
          font-size: inherit;
          background-color: transparent;
          resize: none;
          box-sizing: border-box;
        }

        .button {
          margin-top: 20px;
          width: 40px;
          height: 40px;
          border-radius: 50%;
          background-image: url("@/assets/send.png");
          background-size: cover;
          cursor: pointer;
          transition: all 0.2s;
        }

        .button:active {
          opacity: 0.6;
        }

        .button-none {
          opacity: 0.6;
          cursor: no-drop;
        }
      }
    }
  }
}
</style>

<style lang="scss" scoped>
@import url("@/style/test.scss");
.scroll {
  overflow: auto;
}
.scroll::-webkit-scrollbar {
  width: 8px; /* 滚动条宽度 */
}

.scroll::-webkit-scrollbar-track {
  background-color: transparent; /* 滚动条轨道背景颜色 */
}

.scroll::-webkit-scrollbar-thumb {
  background-color: #cccccc; /* 滚动条拇指颜色 */
  border-radius: 4px; /* 滚动条拇指圆角 */
  transition: all 0.35s;
}

.scroll::-webkit-scrollbar-thumb:hover {
  background-color: #555; /* 滚动条拇指颜色（鼠标悬停） */
}
</style>
